package IC.lir;

import IC.AST.Visitor;
import IC.AST.BinaryOperationExpression;
import IC.AST.UnaryOperationExpression;
import IC.AST.LiteralExpression;
import IC.AST.IntegerLiteral;
import IC.AST.BooleanLiteral;
import IC.AST.NullLiteral;
import IC.AST.QuoteLiteral;

import IC.SymbolTables.Types.*;
import IC.SymbolTables.Types.BasicType.BasicTypeEnum;

public class ImmediatesCalcVIsitor extends Visitor 
{
	public Object Visit(BinaryOperationExpression node)
	{
		if (node.GetFirstExp().IsExpValueSet() && node.GetSecondExp().IsExpValueSet())
		{
			if (node.GetType().equals(new BasicType(BasicTypeEnum.BOOL)))
				node.SetExpValue(node.GetOperation().EvaluateBooleanExpression(
						node.GetFirstExp().GetExpValue(), node.GetSecondExp().GetExpValue()));
			else if (node.GetType().equals(new BasicType(BasicTypeEnum.INT)))
				node.SetExpValue(node.GetOperation().EvaluateIntegerExpression(
						node.GetFirstExp().GetExpValue(), node.GetSecondExp().GetExpValue()));
			else if (node.GetType().equals(new BasicType(BasicTypeEnum.STRING)))
				node.SetExpStringValue(node.GetFirstExp().GetExpStringValue() + node.GetSecondExp().GetExpStringValue());
		}
		return null;
	}
	
	public Object Visit(UnaryOperationExpression node)
	{
		if (node.GetExpression().IsExpValueSet())
		{
			if (node.GetOperation().equals(UnaryOperationExpression.Operation.Minus))
				node.SetExpValue(-node.GetExpression().GetExpValue());
			else
				node.SetExpValue(node.GetExpression().GetExpValue() == 1 ? true : false);
		}
		return null;
	}
	
	public Object Visit(LiteralExpression node)
	{
		if (node.GetLiteral().IsExpValueSet())
		{
			if (node.GetLiteral() instanceof QuoteLiteral)
				node.SetExpStringValue(node.GetLiteral().GetExpStringValue());
			else
				node.SetExpValue(node.GetLiteral().GetExpValue());
		}
		return null;
	}
	
	public Object Visit(IntegerLiteral node)
	{
		node.SetExpValue(node.GetVaule());
		return null;
	}
	
	public Object Visit(BooleanLiteral node)
	{
		node.SetExpValue(node.GetVaule());
		return null;
	}
	
	public Object Visit(NullLiteral node)
	{ 
		node.SetExpValueToNull();
		return null;
	}
	
	public Object Visit(QuoteLiteral node)
	{
		node.SetExpStringValue(node.GetValue());
		return null;
	}
}
